package com.jihui.jihuipicturebackend.manager.upload;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import com.jihui.jihuipicturebackend.config.CosClientConfig;
import com.jihui.jihuipicturebackend.exception.BusinessException;
import com.jihui.jihuipicturebackend.exception.ErrorCode;
import com.jihui.jihuipicturebackend.manager.CosManager;
import com.jihui.jihuipicturebackend.model.dto.file.UploadPictureResult;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;


@Slf4j
public abstract class FileManagerUploadTemplate {

    @Resource
    CosClientConfig cosClientConfig;

    @Resource
    CosManager cosManager;

    /**
     * 上传图片
     * @param inputSource
     * @param uploadPathPrefix
     * @return
     */
    public final UploadPictureResult uploadPicture(Object inputSource, String uploadPathPrefix){
        // 参数校验
        validateParams(inputSource, uploadPathPrefix);

        String uuid = UUID.randomUUID().toString();
        // 获取文件名及其文件后缀
        String originalFilename = getOriginalFilename(inputSource);
        String fileSuffix = FileUtil.getSuffix(originalFilename);

        String uploadFileName = String.format("%s_%s.%s", uuid, DateUtil.formatDate(new Date()), fileSuffix);
        String uploadPath = String.format("/%s/%s", uploadPathPrefix, uploadFileName);
        // 处理Ai图片的url地址
        if (uploadPath.contains("?")) {
            uploadPath = uploadPath.substring(0, uploadPath.indexOf("?"));
        }
        File tempFile = null;
        try {
            // 转存文件到临时文件
            tempFile = File.createTempFile(uploadPath, null);
            processFile(inputSource, tempFile);
            // 上传文件到cos
            PutObjectResult putObjectResult = cosManager.putPictureObject(uploadPath, tempFile);
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
            ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();
            List<CIObject> objectList = processResults.getObjectList();
            if (CollUtil.isNotEmpty(objectList)) {
                CIObject compressedCiObject = objectList.get(0);
                CIObject thumbnailResult = compressedCiObject;
                if(objectList.size() > 1){
                    thumbnailResult = objectList.get(1);
                }
                // 封装压缩图返回结果
                return getUploadPictureResult(originalFilename, compressedCiObject,thumbnailResult,imageInfo);
            }
            // 返回结果
            return getUploadPictureResult(originalFilename, uploadPath, tempFile,imageInfo);
        } catch (Exception e) {
            log.error("上传文件失败 + {}", e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传文件失败");
        } finally {
            extracted(tempFile);
        }

    }


    /**
     * 验证参数
     * @param inputSource
     * @param uploadPathPrefix
     */
    public abstract void validateParams(Object inputSource, String uploadPathPrefix) ;

    /**
     * 获取文件后缀
     * @return
     */
    public abstract String getOriginalFilename(Object inputSource);

    /**
     * 转存文件
     * @param inputSource
     */
    public abstract void processFile(Object inputSource, File tempFile) throws Exception;

    /**
     * 获取上传结果
     *
     * @param originalFilename
     * @param uploadPath
     * @param tempFile
     * @param imageInfo
     * @return
     */
    private UploadPictureResult getUploadPictureResult(String originalFilename, String uploadPath, File tempFile, ImageInfo imageInfo) {

        UploadPictureResult uploadPictureResult = new UploadPictureResult();
        int picWidth = imageInfo.getWidth();
        int picHeight = imageInfo.getHeight();
        double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();

        uploadPictureResult.setPicName(originalFilename.substring(0, originalFilename.lastIndexOf(".")));
        uploadPictureResult.setPicWidth(picWidth);
        uploadPictureResult.setPicHeight(picHeight);
        uploadPictureResult.setPicScale(picScale);
        uploadPictureResult.setPicFormat(imageInfo.getFormat());
        uploadPictureResult.setPicSize(FileUtil.size(tempFile));
        // 设置图片平均色
        uploadPictureResult.setPicColor(imageInfo.getAve());
        uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + uploadPath);
        return uploadPictureResult;
    }

    /**
     * 获取压缩图上传结果
     * @param originFilename 原始图片名
     * @param compressedCiObject 压缩后的图片对象
     * @return
     */
    private UploadPictureResult getUploadPictureResult(String originFilename, CIObject compressedCiObject,CIObject thumbnailResult,ImageInfo imageInfo) {
        UploadPictureResult uploadPictureResult = new UploadPictureResult();
        int picWidth = compressedCiObject.getWidth();
        int picHeight = compressedCiObject.getHeight();
        double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
        uploadPictureResult.setPicName(FileUtil.mainName(originFilename));
        uploadPictureResult.setPicWidth(picWidth);
        uploadPictureResult.setPicHeight(picHeight);
        uploadPictureResult.setPicScale(picScale);
        uploadPictureResult.setPicFormat(compressedCiObject.getFormat());
        uploadPictureResult.setPicSize(compressedCiObject.getSize().longValue());
        // 设置图片平均色
        uploadPictureResult.setPicColor(imageInfo.getAve());
        // 设置图片为压缩后的地址
        uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + compressedCiObject.getKey());
        // 设置缩略图地址
        uploadPictureResult.setThumbnailUrl(cosClientConfig.getHost() + "/" + thumbnailResult.getKey());
        return uploadPictureResult;
    }



    public void deletePicture(String key){
        try{
            cosManager.deleteObject(key);
        }catch (Exception e) {
            log.error("删除文件失败 + {}", e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除文件失败");
        }
    }

    /**
     * 删除临时文件
     * @param tempFile
     */
    private void extracted(File tempFile) {
        if (tempFile != null) {
            boolean deleteFile = tempFile.delete();
            if (!deleteFile) {
                log.error("删除临时文件失败 + {}", tempFile.getAbsolutePath());
            }
        }
    }







}
